#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <memory>
using namespace std;
static const string jsep = "\r\n";
// 设计协议的报头和报文的完整格式
//"len"/r/n{json}/r/n ----len有效载荷长度
//  /r/n:区分len和json串 第二个是为了方便打印

// 添加报头
string Encode(const string &jsonstr)
{
    int len = jsonstr.size();
    string lenstr = to_string(len);
    return lenstr + jsep + jsonstr + jsep;
}
string Decode(string &packagestream)
{
    auto pos = packagestream.find(jsep);
    if (pos == std::string::npos) //
        return "";
    string lenstr = packagestream.substr(0, pos); // 保证长度有
    int len = std::stoi(lenstr);
    int total = lenstr.size() + len + 2 * jsep.size(); // 完整报文的长度；
    if (packagestream.size() < total)                  // 没读完整
    {
        return "";
    }
    string jsonstr = packagestream.substr(pos + jsep.size(), len);
    packagestream.erase(0, total);
    return jsonstr;
}
class Request
{
public:
    Request()
    {
    }
    Request(int x, int y, char oper) : _x(x), _y(y), _oper(oper)
    {
    }
    void Serialize(string *out)
    {
        // jsoncpp
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        Json::FastWriter writer;
        string s = writer.write(root);
        *out = s;
    }
    void Deserialize(const string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if (res)
        {
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _oper = root["oper"].asInt();
        }
        else
            exit(1);
    }
    int X()
    {
        return _x;
    }
    int Y()
    {
        return _y;
    }
    char Oper()
    {
        return _oper;
    }
    void Set(int x,int y,char oper)
    {
        _x=x;
        _y = y;
        _oper = oper;
    }
    ~Request()
    {
    }

private:
    int _x;
    int _y;
    char _oper; //+ - * / %
};
class Response
{
public:
    Response()
    {
    }
    void Serialize(string *out)
    {
        // jsoncpp
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;
        Json::FastWriter writer;
        string s = writer.write(root);
        *out = s;
    }
    void Deserialize(const string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if (res)
        {
            _result = root["result"].asInt();
            _code = root["code"].asInt();
            _desc = root["desc"].asCString();
        }
        else

            exit(1);
    }
    void PrintResult()
    {
        cout << "result:" << _result << " code:" << _code << " desc:" << _desc << endl;
    }
    ~Response()
    {
    }

    int _result=0;
    int _code=0; // 0 :success 1 :div zero 2:非法操作
    string _desc="success";
};
class Factory
{
public:
    static std::shared_ptr<Request> BuildRequest()
    {
        return make_shared<Request>();
    }
    static std::shared_ptr<Response> BuildResponse()
    {
        return make_shared<Response>();
    }
};